#include <ctime>

#include <qapplication.h>
#include "window.moc"
#include "glwidget.h"
#include "ucdinputfile.h"
#include "visHierarchicalClustering.h"
#include "visFlowGuided.h"

//kdTree *tree;

using namespace visualization;
vector<Point> cords;

double xmin, xmax, ymin, ymax, zmin, zmax;
double c[3];
double scale;
size_t n;
size_t parts;
vector<Point> *result;
intgResults *intgCurves;
Model t;
visHierarchicalClustering hc;

class glW: public GLWidget
{
public:
	glW(QWidget *parent = 0) 
	     : GLWidget(parent)
	{}
	~glW()
  {
	}

	GLuint makeObject();
private:

};
class win : public Window
{
public:
	win(glW *glwidget)
		: Window(glwidget)
	{}
	~win(){}
};
void compute(string, vector<Point> *&result);
void continueClustering();
int main(int argc, char *argv[])
{
	compute(argv[1], result);
	c[0] = (xmax + xmin)/2;
	c[1] = (ymax + ymin)/2;
	c[2] = (zmax + zmin)/2;
	if(argc < 2)
	{
		cerr << "Input a data file please..." << endl;
		return 0;
	}
  QApplication app(argc, argv);
  glW *glw = new glW();
  win window(glw);
  window.generateWindow();
  window.show();
	app.exec();

	delete []result;
//	delete []tree;
	return 0;
}

void compute(string filename, vector<Point> *&result)
{

	UCDInputFile file(filename);

	file.FGetModel(t);	
	t.buildKDTree();
	t.getBound(xmin, xmax, ymin, ymax, zmin, zmax);

	cout << "Input the scale..." << endl;
	cin >> scale;

	hc.setDataField(&t);
	cout << "Input the parameter file for streamline generation..." << endl;
	string pfile;
	cin >> pfile;
	hc.setParamFile(pfile);
	cout << "input the number of streamlines: " << endl;
	cin >> n;
	hc.setSeedSources(n);
	double step, maxTime;
	cout << "Input the integration step length..." << endl;
	cin >> step;
	cout << "Input the integration maxLen..." << endl;
	cin >> maxTime;
	hc.setParameters(step, maxTime);

	time_t begin, end;
	hc.computeStreamlines();
	begin = clock();
	hc.initialize();
	end = clock();
	cout << "Time used initialization : " << (double)(end - begin)/CLOCKS_PER_SEC<< endl;

	cout << "Parts = 5..." << endl;
	parts = 5;
	//cin >> parts;
	cout << "Input the pre-process termination distance..." << endl;
	double predist;
	cin >> predist;
	cout << "Input the termination distance..." << endl;
	double dist;
	cin >> dist;

	begin = (double)clock();
	hc.partition(parts, predist, dist);
	end = (double)clock();
	cout << "Time used for clustering	:	" << (double)(end - begin)/CLOCKS_PER_SEC << endl;

	result = hc.getCenters();
	cout << filename << endl;
	if( "data/yuanzhuraoliu.inp" == filename)
	{
		hc.cylinder();
		cords = hc.cords;
	}
	//tree = hc.lineTree;
}

void continueClustering()
{
}

GLuint glW::makeObject()
{
	GLuint list = glGenLists(1);
	glNewList(list, GL_COMPILE);

	glLineWidth(1.5);

	glBegin(GL_LINES);
	drawFramework(xmin-c[0], xmax-c[0], ymin-c[1], ymax-c[1], zmin-c[2], zmax-c[2], scale);
	glEnd();

	cout << parts << endl;
	glColor3f(0, 0, 0);
	for(size_t i = 0; i < parts; i++)
	{
		glBegin(GL_LINE_STRIP);
		for(size_t j = 0; j < result[i].size(); j++)
		{
			Point tmp = result[i][j];
			glVertex3f( (tmp.getX() - c[0])/scale, (tmp.getY()-c[1])/scale, (tmp.getZ()-c[2])/scale );
		}
		glEnd();
	}
	glBegin(GL_POINTS);
	for(size_t i = 0; i < cords.size(); i++)
	{
		glVertex3f( (cords[i].getX() - c[0])/scale, 
								(cords[i].getY() - c[1])/scale,
								(cords[i].getZ() - c[2])/scale
							);
	}
	glEnd();

//	glPointSize(2);
//	glColor3f(0, 0, 0);
//	glBegin(GL_POINTS);
//	for(size_t j = 0; j < 51; j++)
//	{
//		for(size_t i = 0; i < 40 * 5; i++)
//		{
//			glVertex3f( (tree[j].kdNodes[i].pos[0]-c[0])/scale,
//								  (tree[j].kdNodes[i].pos[1]-c[1])/scale,
//									(tree[j].kdNodes[i].pos[2]-c[2])/scale
//								);
//		}
//	}
//	glEnd();

//
//	for(size_t i = 0; i < (*intgCurves).size(); i++)
//	{
//		glBegin(GL_LINE_STRIP);
//		for(size_t j = 0; j < (*intgCurves)[i].size(); j++)
//		{
//			glVertex3f( ((*intgCurves)[i][j].getX()-c[0])/scale, 
//									((*intgCurves)[i][j].getY()-c[1])/scale, 
//								  ((*intgCurves)[i][j].getZ()-c[2])/scale);
//		}
//		glEnd();
//	}

	glEndList();
	return list;
}
